package hu.myai.api.indicators;

import hu.myai.api.tick.AbstractTickConsumer;
import hu.myai.api.tick.TickConsumerInterface;
import hu.myai.model.IndicatorVO;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @author bozbalint
 * */
public abstract class AbstractIndicatorConsumer extends AbstractTickConsumer implements IndicatorConsumerInterface, TickConsumerInterface {

    /**
     * Name of the consumer
     */
    protected String name;

    /**
     * Collection of the arrived indicators
     */
    protected Map<String, IndicatorVO> indicatorMap = new HashMap<String, IndicatorVO>();

    /**
     * Collection of the names of necessary indicators. It is to check if a
     * calculation can start.
     */
    protected List<String> indicatorNameList = new ArrayList<String>();

    /**
     * @return the value of name
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * @param name
     */
    @Override
    public void setName(String name) {
        this.name = name;
    }

    /**
     * The method accept an indicator result. Check if all the expected
     * indicators added their values to the trigger calculation
     */
    @Override
    public void addIndicator(String indicatorName, IndicatorVO indicatorValue) {

        // add inbounds value to the list
        indicatorMap.put(indicatorName, indicatorValue);

        startCalculation();
    }

    @Override
    abstract protected void startCalculation();

    /**
     * Check whenever all the indicator values are received or not. If all the
     * indicators have arrived the calculation can start.
     * */
    protected boolean checkIndicatorCompleteness() {

        // validate if all registered indicators are populated.
        for (String indicatorName : indicatorNameList) {
            if (!indicatorMap.containsKey(indicatorName)) {
                return false;
            }
        }
        return true;
    }

    /**
     * When an trigger or indicator registers itself in an indicator
     * (addListeningTrigger) than the indicator registers itself using this
     * method
     * */
    public boolean addIndicatorNameForCheck(String nameForCheck) {

        if (indicatorNameList.contains(nameForCheck)) {
            System.out.println("Error - indicator already registered!");
            return false;
        } else {
            indicatorNameList.add(nameForCheck);
            return true;
        }
    }

    /**
     * When an trigger removes itself from an indicator (removeListeningTrigger)
     * than the indicator unregisters itself using this method. This is because
     * of the 2 way dependency.
     * */
    public boolean removeIndicatorNameForCheck(String nameForCheck) {

        if (indicatorNameList.remove(nameForCheck)) {
            return true;
        } else {
            System.out.println("Error - indicator is not known, cannot unregister!");
            return false;
        }
    }
}
